﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace FastIM
{
    public interface IServerDiscover
    {
        /// <summary>
        /// 根据客户端id选择集群服务，做负载均衡
        /// </summary>
        /// <param name="clientId"></param>
        /// <returns></returns>
        public string SelectServer(ImClientOptions options, string clientId);
    }
    /// <summary>
    /// 根据hash负载分区规则：clientId转换为hash，根据服务器个数求模
    /// </summary>
    public class HashServerDiscover : IServerDiscover
    {
        /// <summary>
        /// 计算字符串的hash
        /// </summary>
        /// <param name="read"></param>
        /// <returns></returns>
        public static long Hash(string read)
        {
            UInt64 hashedValue = 3074457345618258791ul;
            for (int i = 0; i < read.Length; i++)
            {
                hashedValue += read[i];
                hashedValue *= 3074457345618258799ul;
            }
            return Math.Abs((long)(hashedValue - 9223372036854775808));
        }
        /// <summary>
        /// 根据hash负载分区规则：clientId转换为hash，根据服务器个数求模
        /// </summary>
        /// <param name="options"></param>
        /// <param name="clientId"></param>
        /// <returns></returns>
        public string SelectServer(ImClientOptions options, string clientId)
        {
            string[] _servers = options.Servers;
            //var servers_idx = int.Parse(clientId.ToString("N").Substring(28), NumberStyles.HexNumber) % _servers.Length;
            var servers_idx = Hash(clientId.ToString()) % _servers.Length;
            if (servers_idx >= _servers.Length) servers_idx = 0;
            return _servers[servers_idx];
        }
    }
}
